#pragma once
/*
 *  SBJ/NXT/Device.h
 *  NXTFace
 *
 *  Created by David Giovannini on 8/23/06.
 *  Copyright 2006 Software by Jove. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include "SBJ/NXT/Error.h"
#include "SBJ/NXT/Output.h"
#include "SBJ/NXT/Input.h"

#include <string>

namespace nFANTOM100 { class iNXT; }

namespace SBJ
{

namespace NXT
{

struct ConnectInfo
{
	ConnectInfo( void )
	: btConnected( false ) {}
	ConnectInfo( const std::string& rn )
	: deviceSessionName( rn ), btConnected( false ) {}
	std::string deviceSessionName;
	bool btConnected;
	std::string btName;
	std::string btPasskey;
};

struct DeviceVersion
{
	DeviceVersion( void )
	: m_version( 0 )
	{
	}
	
	DeviceVersion(
		unsigned char protocalMajor,
		unsigned char protocolMinor,
		unsigned char firmwareMajor,
		unsigned char firmwareMinor )
	: m_version( ( protocalMajor << 24 ) | ( protocolMinor << 16 ) | ( firmwareMajor << 8 ) | ( firmwareMinor << 0 ) )
	{
	}
	
	unsigned char protocolMajor( void ) const { return ( m_version & 0xFF000000 ) >> 24; }
	unsigned char protocolMinor( void ) const { return ( m_version & 0x00FF0000 ) >> 16; }
	unsigned char firmwareMajor( void ) const { return ( m_version & 0x0000FF00 ) >> 8; }
	unsigned char firmwareMinor( void ) const { return ( m_version & 0x000000FF ) >> 0; }
	
	operator long ( void ) const { return m_version; };
	
	bool isEmpty( void ) const { return m_version == 0; }
	
	std::string toString( void ) const
	{
		char buffer[ 256 ];
		::sprintf( buffer, "P.%d.%d-F.%d.%d", protocolMajor(), protocolMinor(), firmwareMajor(), firmwareMinor() );
		return buffer;
	}
	
private:
	long m_version;
};
	
struct DeviceInfo
{
	DeviceVersion devVers;
	ConnectInfo connect;
	std::string name;
	std::string bluetoothAddress;
	unsigned char signalStrength[ 4 ];
	unsigned int freeSpace;
	int status;
};

class Device
{
public:	
// Construction
	Device( const std::string& resourceName, nFANTOM100::iNXT* opaqueRep );
	
	~Device( void );
	
// Accessors
	bool isBluetooth( void ) const;
	
	operator bool ( void ) const;
	
	const DeviceVersion& getVersion( void ) const;
	
	DeviceInfo getInfo( void ) const;
	
	std::string getName( void ) const;
	
	const std::string& getSessionName( void ) const;
	
	Error setName( const std::string& name );
	
	double getBatteryLevel( void );
	
	std::string getProgramName( void );
	
	Output& getOutput( OutputPort port );
	
	Input& getInput( InputPort port );
	
// Manipulators
	bool connect( const std::string& passKey );
	
	void runProgram( const std::string& program );
	
	void stopProgram( void );
	
	void playTone( unsigned short hrz, double secs );
	
	void sendMessage( const std::string& msg, unsigned char box );
	
	std::string waitForMessage( unsigned char box, bool clear );
	
	std::string getLocalMessage( unsigned char box, bool clear );

	std::string getRemoteMessage( unsigned char box, bool clear );
	
	Error sendCommand( const char* stream, size_t len, char* resultStream, size_t resultSize );
	
private:
	nFANTOM100::iNXT* m_opaqueRef;
	ConnectInfo m_connectInfo;
	DeviceVersion m_version;
	Output m_outputA;
	Output m_outputB;
	Output m_outputC;
	Input m_input1;
	Input m_input2;
	Input m_input3;
	Input m_input4;
};

void print( const DeviceInfo& info );

}

}


/*
iFile * 	createFile (ViConstString fileName, tStatus &status);
void 	destroyFile (iFile *filePtr);
iFileIterator * 	createFileIterator (ViConstString fileNamePattern, tStatus &status);
void 	destroyFileIterator (iFileIterator *fileIteratorPtr);
iModule * 	createModule (ViConstString moduleName, ViUInt32 moduleID, ViUInt32 moduleSizeInBytes, ViUInt32 ioMapSizeInBytes, tStatus &status);
void 	destroyModule (iModule *modulePtr);
iModuleIterator * 	createModuleIterator (ViConstString moduleNamePattern, tStatus &status);
void 	destroyModuleIterator (iModuleIterator *moduleIteratorPtr);
void 	downloadFirmware (const ViByte firmwareBufferPtr[], ViUInt32 firmwareBufferSizeInBytes, tStatus &status);
ViUInt32 	write (const ViByte bufferPtr[], ViUInt32 numberOfBytes, tStatus &status);
ViUInt32 	read (ViPBuf bufferPtr, ViUInt32 numberOfBytes, tStatus &status);
void 	bootIntoFirmwareDownloadMode (tStatus &status);
void 	eraseUserFlash (tStatus &status);
ViUInt32 	pollAvailableLength (tBuffer bufferSelector, tStatus &status);
ViUInt32 	readBufferData (ViPBuf dataBuffer, tBuffer bufferSelector, ViUInt32 numberOfBytesToRead, tStatus &status);
void 	getResourceString (ViChar resourceString[], tStatus &status);
void 	bluetoothFactoryReset (tStatus &status);
*/

